﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Controls.Maps;
using System.Device.Location;
using System.Windows.Media.Imaging;
using System.Collections.ObjectModel;
using MapTest.Element;

namespace MapTest
{
    public partial class MainPage : PhoneApplicationPage
    {
        private MapLayer DialogLayer;
        PushpinLayer pushpinLayer;
        // Constructor
        public MainPage()
        {
            InitializeComponent();
            map.Mode = new RoadMode();
            DialogLayer = new MapLayer();
            pushpinLayer = new PushpinLayer();
            map.Children.Add(DialogLayer);
            map.Children.Add(pushpinLayer.layer);
            //map.MouseLeftButtonUp += new MouseButtonEventHandler(pushpin_HideDialog);
            StartLocationService(GeoPositionAccuracy.High);

        }

        /// <summary>
        /// Helper method to start up the location data acquisition
        /// </summary>
        /// <param name="accuracy">The accuracy level </param>
        private void StartLocationService(GeoPositionAccuracy accuracy)
        {
            GeoCoordinateWatcher watcher;
            // Reinitialize the GeoCoordinateWatcher
            watcher = new GeoCoordinateWatcher(accuracy);
            watcher.MovementThreshold = 20;

            // Add event handlers for StatusChanged and PositionChanged events
            watcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged);

            // Start data acquisition
            watcher.Start();
        }
        /// <summary>
        /// Handler for the PositionChanged event. This invokes MyStatusChanged on the UI thread and
        /// passes the GeoPositionStatusChangedEventArgs
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
        {
            Deployment.Current.Dispatcher.BeginInvoke(() => MyPositionChanged(e));
        }

        /// <summary>
        /// Custom method called from the PositionChanged event handler
        /// </summary>
        /// <param name="e"></param>
        void MyPositionChanged(GeoPositionChangedEventArgs<GeoCoordinate> e)
        {
            //set map view to given coordinate
            GeoCoordinate coordinate = new GeoCoordinate(e.Position.Location.Latitude, e.Position.Location.Longitude);
            map.SetView(coordinate, 15);

            //put central image to the central of map
            Image image = new Image();
            image.Source = new BitmapImage(new Uri("images/people.png", UriKind.Relative));
            image.Stretch = Stretch.None;
            MapLayer CentralLayer = new MapLayer();
            CentralLayer.AddChild(image, coordinate, new PositionOrigin(0.5, 0.5));

            //add central imageto map view
            map.Children.Add(CentralLayer);

            //draw circle
            MapPolygon poly = new MapPolygon();
            LocationCollection points = drawCircle(500, 36, coordinate);
            poly.Locations = points;   //Where points is a List<LocationCollection> object

            //Set the fill and stroke color of circle
            poly.Fill = new SolidColorBrush(Color.FromArgb(50, 110, 160, 216));
            poly.Stroke = new SolidColorBrush(Color.FromArgb(200, 110, 160, 216));
            poly.StrokeThickness = 2;

            //add the circle to map view
            map.Children.Add(poly);
        }

        LocationCollection drawCircle(double radius, int pointCnt, GeoCoordinate central)
        {
            radius *= 0.00001;
            LocationCollection points = new LocationCollection();
            for (double angle = 0; angle < 2 * Math.PI; angle += 2 * Math.PI / pointCnt)
            {
                double x = central.Latitude + Math.Cos(angle) * radius;
                double y = central.Longitude + Math.Sin(angle) * radius;
            
                points.Add(new GeoCoordinate(x, y));
            }
            return points;
        }
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            map.SetView(new GeoCoordinate(23.6, 121.5), 13);
            pushpinLayer.AddChild("台灣大學新生南路地下停車場", "台北市blabla", new GeoCoordinate(23.6, 121.5)).MouseEnter += new MouseEventHandler(pushpin_ShowDialog);
            pushpinLayer.AddChild("台灣大學綜合體育館地下停車場", "blabla", new GeoCoordinate(23.63, 121.5)).MouseEnter += new MouseEventHandler(pushpin_ShowDialog);
        }
        public void pushpin_ShowDialog(object sender, MouseEventArgs e)
        {
            shownPin = null;
            DialogLayer.Children.Clear();

            //get the location of pushpin
            GeoCoordinate coordinate = ((Pushpin)sender).Location;

            //create a new name bar canvas
            Canvas namaBarCanvas = new Canvas();
            namaBarCanvas.Width = 430;
            namaBarCanvas.Height = 90;
            ImageBrush imgBrush = new ImageBrush() { ImageSource = new BitmapImage(new Uri("images/namebar.png", UriKind.Relative)) };
            namaBarCanvas.Background = imgBrush;

            //set the name
            TextBlock pinName = new TextBlock();
            pinName.Text = ((Pushpin)sender).Name.ToString();
            pinName.VerticalAlignment = System.Windows.VerticalAlignment.Center;
            pinName.FontSize = 25;

            //add name to name bar
            namaBarCanvas.Children.Add(pinName);
            Canvas.SetLeft(pinName, 10);
            Canvas.SetTop(pinName, 1);

            //set the address
            TextBlock pinAddr = new TextBlock();
            pinAddr.Text = ((Pushpin)sender).DataContext.ToString();
            pinAddr.VerticalAlignment = System.Windows.VerticalAlignment.Center;
            pinAddr.FontSize = 18;

            //add name to name bar
            namaBarCanvas.Children.Add(pinAddr);
            Canvas.SetLeft(pinAddr, 10);
            Canvas.SetTop(pinAddr, 36);

            //set the more info button
            Button moreInfoBtn = new Button();
            moreInfoBtn.Background = new ImageBrush() { ImageSource = new BitmapImage(new Uri("images/namebar_btn.png", UriKind.Relative)) };
            moreInfoBtn.DataContext = ((Pushpin)sender).Name;
            moreInfoBtn.BorderThickness = new Thickness(0);
            moreInfoBtn.Width = 65;
            moreInfoBtn.Height = 65;
            //set event handler
            moreInfoBtn.Click += new RoutedEventHandler(Dialog_Click);

            //add button to name bar
            namaBarCanvas.Children.Add(moreInfoBtn);
            Canvas.SetLeft(moreInfoBtn, 360);
            Canvas.SetTop(moreInfoBtn, 2);

            //add name bar to dialog layer
            DialogLayer.AddChild(namaBarCanvas, coordinate, new PositionOrigin(0.5, 1.7));
            shownPin = (Pushpin)sender;
        }
        private Pushpin shownPin = null;
        public void pushpin_HideDialog(object sender, MouseEventArgs e)
        {
            if (shownPin == null) return;
            //shownPin.MouseLeftButtonUp -= new MouseButtonEventHandler(pushpin_HideDialog);
            //shownPin.MouseLeftButtonUp += new MouseButtonEventHandler(pushpin_ShowDialog);
            shownPin = null;
            DialogLayer.Children.Clear();
        }
        public void Dialog_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show((string)((Button)sender).DataContext);
        }
    }
}